//
//  EZTallyArray.h
//  zhaitu
//
//  Created by ellzu on 13-8-3.
//  Copyright (c) 2013年 ellzu. All rights reserved.
//

#ifndef __zhaitu__EZTallyArray__
#define __zhaitu__EZTallyArray__

#include <iostream>
#include "EZTallyObject.h"
#include <vector>

namespace EZTally {
    
    template <class _value>
    class EZTallyArray : public EZTallyObject
    {
    private:
        std::vector<_value> objects;
        void CopyOther(const EZTallyArray &other);
    protected:
        
    public:
        EZTallyArray();
        EZTallyArray(const EZTallyArray &other);
        EZTallyArray &operator=(const EZTallyArray &other);
        ~EZTallyArray();
        
        void AddObject(const _value obj);
        void RemoveObject(_value obj);
        void RemoveObjectAtIndex(int index);
        void Clear();
        _value ObjectAtIndex(int index);
        int IndexOfObject(_value obj);
        int Count();
        _value LastObject();
    };
    
}




using namespace EZTally;

template <class _value>
EZTallyArray<_value>::EZTallyArray()
{
//    std::cout << "new EZTallyArray" << std::endl;
}
template <class _value>
EZTallyArray<_value>::~EZTallyArray()
{
    typename std::vector<_value>::iterator it = objects.begin();
    for (; it!=objects.end(); it++) {
        EZTallyObject *o = *it;
        o->Release();
    }
//    std::cout << "~EZTallyArray" <<std::endl;
}

template <class _value>
EZTallyArray<_value>::EZTallyArray(const EZTallyArray &other)
{
    //    std::cout << "EZTallyArray other" <<std::endl;
    CopyOther(other);
}

template <class _value>
EZTallyArray<_value>&  EZTallyArray<_value>::operator=(const EZTallyArray &other)
{
    //    std::cout << "EZTallyArray =" <<std::endl;
    CopyOther(other);
    return *this;
}

template <class _value>
void EZTallyArray<_value>::CopyOther(const EZTallyArray &other)
{
    objects = other.objects;
    typename std::vector<_value>::iterator it = objects.begin();
    for (; it!=objects.end(); it++) {
        EZTallyObject *o = *it;
        o->Retain();
    }
}


template <class _value>
void EZTallyArray<_value>::AddObject(_value obj)
{
    EZTallyObject *eobj = static_cast<EZTallyObject*>(obj);
    if(eobj==0){
        return ;
    }
    eobj->Retain();
    objects.push_back(obj);
}

template <class _value>
void EZTallyArray<_value>::RemoveObject(_value obj)
{
    int index = IndexOfObject(obj);
    RemoveObjectAtIndex(index);
//    std::vector<EZTallyObject*>::iterator it = objects.begin();
//    for (; it !=objects.end(); it++) {
//        EZTallyObject *o = *it;
//        if ( o==obj) {
//            o->Release();
//            objects.erase(it);
//            it--;
//        }
//    }

    
}

template <class _value>
void EZTallyArray<_value>::RemoveObjectAtIndex(int index)
{
    if(index<0 || index>=Count()){
        return;
    }
    typename std::vector<_value>::iterator it = objects.begin()+index;
    objects.erase(it);
}

template <class _value>
void EZTallyArray<_value>::Clear()
{
    objects.clear();
}
template <class _value>
_value EZTallyArray<_value>::ObjectAtIndex(int index)
{
    return objects.at(index);
}

template <class _value>
_value EZTallyArray<_value>::LastObject()
{
    if(Count()>0){
        return ObjectAtIndex(Count()-1);
    }else{
        return 0;
    }
}


template <class _value>
int EZTallyArray<_value>::IndexOfObject(_value obj)
{
    int i=0;
    for (; i<(int)objects.size(); i++) {
        EZTallyObject *o = objects.at(i);
        if (o==obj) {
            break;
        }
    }
    if (i == (int)objects.size()) {
        i=-1;
    }
    return i;
}
template <class _value>
int EZTallyArray<_value>::Count()
{
    return objects.size();
}

#endif /* defined(__zhaitu__EZTallyArray__) */
